package com.vol.sys;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vol.RedisUtils;
import com.vol.controllerparams.PageParams_Role;
import com.vol.entity.*;
import com.vol.entity.pager.PageParams;
import com.vol.entity.pager.ResultPager;
import com.vol.mapper.SysMenuMapper;
import com.vol.mapper.SysRoleMapper;
import com.vol.mapper.SysRoleauthMapper;
import com.vol.model.Sys_Actions;
import com.vol.requestparams.QuanxianParams;
import com.vol.utils.RolesUtils;
import com.vol.utils.UserContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class RoleService {
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysRoleauthMapper sysRoleauthMapper;
    @Autowired
    private RolesUtils rolesUtils;
    @Autowired
    private UserContext userContext;

    @Autowired
    private RedisUtils<List<Map<String, Object>>> redisUtils_Menu;


    public ResultPager<SysRole> getPageData(PageParams_Role pageParams) {
        UserInfo userInfo = userContext.getUserInfo();
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern("yyyy-MM-dd HH:mm:ss");
        Page<SysRole> page = new Page<>(pageParams.getPage(), pageParams.getRows());
        QueryWrapper<SysRole> qw = new QueryWrapper<SysRole>();
        if (pageParams.getOrder().equals("desc")) {
            qw.orderByDesc(pageParams.getSort());
        } else if (pageParams.getOrder().equals("asc")) {
            qw.orderByAsc(pageParams.getSort());
        }
        qw.eq("Role_Id",pageParams.value);

        sysRoleMapper.selectPage(page, qw);
        List<SysRole> records = page.getRecords();

        ResultPager<SysRole> resultPager = new ResultPager<>();
        resultPager.setStatus(0);
        resultPager.setRows(records);
        resultPager.setTotal((int) page.getTotal());
        return resultPager;
    }


    public List<Map<String, Object>> getUserChildRoles(boolean is_parent_id_set_0) {
        UserInfo userInfo = userContext.getUserInfo();
        int RoleId=userInfo.getRole_Id();
        List<Integer> AllChildRoles = rolesUtils.getAllChildRoles();

        LambdaQueryWrapper<SysRole> qw = new LambdaQueryWrapper<>();
        for (Integer roleIds : AllChildRoles) {
            qw.or().eq(SysRole::getRoleId, roleIds);
        }

        List<SysRole> list = sysRoleMapper.selectList(qw);

        if (list.size() > 0 && is_parent_id_set_0) {
            list.get(0).setParentid(0);
        }

        List<Map<String, Object>> listmap = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", list.get(i).getRoleId());
            map.put("parentId", list.get(i).getParentid());
            map.put("roleName", list.get(i).getRolename());
            listmap.add(map);
        }
        return listmap;
    }

    public Map<String, Object> getCurrentTreePermission() throws JsonProcessingException {
        UserInfo userInfo = userContext.getUserInfo();
        int RoleId = userInfo.getRole_Id();
        Map<String, Object> resultMap = new HashMap<>();
        //==================获取tree===============//
        List<SysMenu> menuList = null;
        if (RoleId == 1) {
            menuList = sysMenuMapper.selectList(null);
        } else {
            menuList = sysMenuMapper.selectAllMenuAuth(RoleId);
        }

        List<Map<String, Object>> menuMap = new ArrayList<>();
        for (SysMenu sysMenu : menuList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", sysMenu.getMenuId());
            map.put("pid", sysMenu.getParentid());
            map.put("text", sysMenu.getMenuname());
            map.put("isApp", false);
            ObjectMapper objectMapper = new ObjectMapper();
            Sys_Actions[] Actions = objectMapper.readValue(sysMenu.getAuth(), Sys_Actions[].class);
            map.put("actions", Actions);
            menuMap.add(map);
        }
        resultMap.put("tree", menuMap);
        //==================获取roles===============//
        resultMap.put("roles", this.getUserChildRoles(false));
        return resultMap;
    }

    public List<Map<String, Object>> getUserTreePermission(Integer roleId) throws JsonProcessingException {
        List<SysMenu> menuList = sysMenuMapper.selectAllMenuAuth(roleId);
        List<Map<String, Object>> menuMap = new ArrayList<>();
        for (SysMenu sysMenu : menuList) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", sysMenu.getMenuId());
            map.put("pid", sysMenu.getParentid());
            map.put("text", sysMenu.getMenuname());
            map.put("isApp", false);
            ObjectMapper objectMapper = new ObjectMapper();
            Sys_Actions[] Actions = objectMapper.readValue(sysMenu.getAuth(), Sys_Actions[].class);
            List<Sys_Actions> listActions = new ArrayList<>();
            List<String> authValueList = Arrays.asList(sysMenu.getAuthvalue().split(","));
            for(Sys_Actions action:Actions){
                if(authValueList.contains(action.getValue())){
                    listActions.add(action);
                }
            }
            Sys_Actions[] Actions2 = listActions.toArray(new Sys_Actions[0]);
            map.put("actions", Actions2);
            menuMap.add(map);

        }
        return menuMap;
    }

    @Transactional
    public void SavePermission(int roleId,List<QuanxianParams> listQx) throws JsonProcessingException {
        UserInfo userInfo = userContext.getUserInfo();
        //第一步：删除改角色下的所有权限
        LambdaQueryWrapper<SysRoleauth> qw = new LambdaQueryWrapper<>();
        qw.eq(SysRoleauth::getRoleId, roleId);
        sysRoleauthMapper.delete(qw);
        //第二步：添加新设置的角色权限
        for (QuanxianParams quanxianParams : listQx) {
            SysRoleauth sysRoleauth = new SysRoleauth();
            List<Sys_Actions> actions = quanxianParams.getActions();
            String Authvalue = "";
            for (Sys_Actions sysActions : actions) {
                Authvalue = Authvalue + sysActions.getValue() + ",";
            }
            if (Authvalue.length() > 0) {
                Authvalue = Authvalue.substring(0, Authvalue.length() - 1);
            }
            sysRoleauth.setAuthvalue(Authvalue);
            sysRoleauth.setCreatedate(new Date());
            sysRoleauth.setCreator(userInfo.getUserName());
            sysRoleauth.setMenuId(quanxianParams.getId());
            sysRoleauth.setRoleId(roleId);
            sysRoleauthMapper.insert(sysRoleauth);
        }
        //第三步：重置菜单缓存
        List<SysMenu> list = null;
        if (roleId == 1) {//管理员角色
            LambdaQueryWrapper<SysMenu> qw_menu = new LambdaQueryWrapper<>();
            qw_menu.orderByDesc(SysMenu::getOrderno, SysMenu::getParentid);
            list = sysMenuMapper.selectList(qw_menu);
        } else {//其他角色
            list = sysMenuMapper.selectAllMenuAuth(roleId);
        }
        List<Map<String, Object>> listmap = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            String Auth = list.get(i).getAuth();
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String>[] Actions = objectMapper.readValue(Auth, Map[].class);
            List<String> valueList = new ArrayList<>();
            for (int j = 0; j < Actions.length; j++) {
                valueList.add(Actions[j].get("value"));
            }

            Map<String, Object> map = new HashMap<>();
            map.put("id", list.get(i).getMenuId());
            map.put("name", list.get(i).getMenuname());
            map.put("url", list.get(i).getUrl());
            map.put("parentId", list.get(i).getParentid());
            map.put("icon", list.get(i).getIcon());
            map.put("enable", list.get(i).getEnable());
            map.put("tableName", list.get(i).getTablename());
            map.put("permission", valueList);
            listmap.add(map);
        }
        redisUtils_Menu.setKey("meunCache" + userInfo.getUser_Id(), listmap);
    }


}
